package com.adxon.data2;

import com.adxon.MsgException;
import com.adxon.servlet.ServletBase;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Map;
import java.util.TreeMap;

import javax.servlet.http.HttpServletRequest;

public class Base{
	private static ThreadLocal<Connection>	cnn=initConn(); 

	public static Connection getConn()throws MsgException{
		try{
			Connection r=cnn.get();
			if(r==null){
				r=DriverManager.getConnection(
						"jdbc:mysql://localhost:3306/test","hans","1234");
				cnn.set(r);
			}
			return r;
		}catch(SQLException e){
			e.printStackTrace();
			throw new MsgException(MsgException.SQL,null);
		}
	}
	private static ThreadLocal<Connection> initConn(){
		try{
			Class.forName("com.mysql.jdbc.Driver");
			return new ThreadLocal<Connection>(); 
		}catch(ClassNotFoundException e){
			e.printStackTrace();
			return null; 
		}
	}
	public static void main(String[] args){
		try{
			Item e;
			e=new Item();
			e.setText("Tes0");
			e.commit();
			long i=e.getId();
			System.out.println(i);
			e=new Item();
			e.update(i);
			System.out.println(e.getText());
		}catch(MsgException e){
			e.printStackTrace();
		}
	}
	public final static String regulate(String string){
		if(string!=null){
			string=string.trim();
			if(string.length()==0)
				string=null;
		}
		return string;
	}

	protected String				bsk;	// base kind
	protected Map<String,Object>	col;	// columns
	protected long					id;		// id
	protected String				pk;		// permalink
	private ResultSet				res;
	protected String				stp;	// columns for setup

	protected void allocateId()throws MsgException{
		try{
			Statement s=getConn().createStatement();
			s.executeUpdate("INSERT k()VALUES()",Statement.RETURN_GENERATED_KEYS);
			ResultSet r=s.getGeneratedKeys(); 
			if(r.next())
				id=r.getInt(1)+ServletBase.site;
			r.close();
			s.close();
		}catch(SQLException e){
			e.printStackTrace();
			throw new MsgException(MsgException.SQL,null);
		}
	}
	public void commit()throws MsgException{
		try{
			String q=null;
			if(id==0){
				allocateId();
				q="INSERT "+bsk;
			}
			col=new TreeMap<String,Object>();
			commitExt();
			if(q==null)
				q="UPDATE "+bsk;
			else{
				StringBuilder k=new StringBuilder(q);
				StringBuilder v=new StringBuilder();
				k.append("(");
				for(String e:col.keySet()){
					k.append(e);
					k.append(",");
					v.append("?,");
				}
				k.append("id)VALUES(");
				v.append("?)");
				q=k.toString()+v.toString();
			}
			System.out.println(q);
			PreparedStatement s=getConn().prepareStatement(q);
			int n=1;
			for(Object e:col.values()){
				if(e==null)
					s.setObject(n,null);
				else{
					String c=e.getClass().getSimpleName();
					if(c.equals("Byte"))
						s.setByte(n,(byte)e);
					else if(c.equals("Integer"))
						s.setInt(n,(int)e);
					else if(c.equals("Long"))
						s.setLong(n,(long)e);
					else if(c.equals("String"))
						s.setString(n,(String)e);
				}
				n++;
			}
			s.setLong(n,id);
			s.executeUpdate();
			s.close();
		}catch(SQLException e){
			e.printStackTrace();
		}
	}
	protected void commit(String column,byte value){
		col.put(column,value);
	}
	protected boolean commit(String column,byte[] value){
		if(value==null)
			return false;
		col.put(column,value);
		return true;
	}
	protected void commit(String column,int value){
		col.put(column,value);
	}
	protected void commit(String column,long value){
		col.put(column,value);
	}
	protected void commit(String column,String value){
		col.put(column,value);
	}
	protected void commitExt()throws MsgException{
	}
	public boolean equals(Base base){
		return base.id==id;
	}
	public void getAll(HttpServletRequest req){
		req.setAttribute("i",this);
	}
	public long getId(){
		return id;
	}
	public void getInfo(HttpServletRequest req)throws MsgException{
		getAll(req);
		req.setAttribute("Page","info.jsp");
	}
	public void getPage(HttpServletRequest req)throws MsgException{
		getAll(req);
		req.setAttribute("Page","page.jsp");
	}
	public void getPost(HttpServletRequest req)throws MsgException{
		getAll(req);
		req.setAttribute("Page","post.jsp");
	}
	public void reset(){
		id=0;
	}
	public void setAll(Base src){
		id=src.id;
		res=src.res;
	}
	public void setAll(HttpServletRequest req)throws MsgException{
	}
	public void setId(Base base){
		id=base.id;
	}
	public void setId(long value){
		id=value;
	}
	public void setup()throws MsgException{
		try{
			Statement s=getConn().createStatement(); 
			s.executeUpdate("DROP TABLE IF EXISTS "+bsk);
			s.executeUpdate("CREATE TABLE "+bsk+"("+stp+")");
			s.close();
		}catch(MsgException e){
			e.printStackTrace();
		}catch(SQLException e){
			e.printStackTrace();
		}
	}
	@Override
	public String toString(){
		return Long.toString(id);
	}
	public final Base update()throws MsgException{
		try{
			PreparedStatement s=getConn().prepareStatement(
					"SELECT * FROM "+bsk+" WHERE id=?");
			s.setLong(1,id);
			res=s.executeQuery();
			if(res.next()){
				updateExt();
				res.close();
				s.close();
			}else{
				res.close();
				s.close();
				throw new MsgException(MsgException.NOT_FOUND,null);
			}
		}catch(SQLException e){
			e.printStackTrace();
		}
		return this;
	}
	public Base update(long id)throws MsgException{
		this.id=id;
		return update();
	}
	public Base update(ResultSet resultSet)throws MsgException{
		return this;
	}
	protected Blob updateBlob(String column)throws MsgException{
		try{
			return res.getBlob(column);
		}catch(SQLException e){
			e.printStackTrace();
			throw new MsgException(MsgException.SQL,null);
		}
	}
	protected byte updateByte(String column)throws MsgException{
		try{
			return res.getByte(column);
		}catch(SQLException e){
			e.printStackTrace();
			throw new MsgException(MsgException.SQL,null);
		}
	}
	protected void updateExt()throws MsgException{
		id=updateLong("id");
	}
	protected int updateInt(String column)throws MsgException{
		try{
			return res.getInt(column);
		}catch(SQLException e){
			e.printStackTrace();
			throw new MsgException(MsgException.SQL,null);
		}
	}
	protected long updateLong(String column)throws MsgException{
		try{
			return res.getLong(column);
		}catch(SQLException e){
			e.printStackTrace();
			throw new MsgException(MsgException.SQL,null);
		}
	}
	protected String updateString(String column)throws MsgException{
		try{
			return res.getString(column);
		}catch(SQLException e){
			e.printStackTrace();
			throw new MsgException(MsgException.SQL,null);
		}
	}
}